#include "TaskDistribute.h"
#include "simodo/lsp-server/ServerContext.h"
#include "parsers/Initialize.h"
#include "parsers/Initialized.h"
#include "parsers/Shutdown.h"
#include "parsers/DocDidOpen.h"
#include "parsers/DocDidChange.h"
#include "parsers/DocDidClose.h"
#include "parsers/DocHover.h"
#include "parsers/DocumentSymbol.h"
#include "parsers/SemanticTokens.h"
#include "parsers/GotoDeclaration.h"
#include "parsers/GotoDefinition.h"
#include "parsers/Completion.h"
#include "parsers/SegmentationFault.h"
#include "parsers/SimodoCommand.h"

#include "simodo/variable/json/Serialization.h"
#include "simodo/variable/json/Rpc.h"
#include "simodo/inout/convert/functions.h"

namespace simodo::lsp
{

void TaskDistribute::work()
{
    variable::JsonRpc json_rpc(_jsonrpc_content);

    /// @note Метод может быть пустым только когда сделаем отправку запросов с сервера на клиент
    if (!json_rpc.is_valid() || json_rpc.method().empty()) {
        _server.log().error("Unrecognized JSON-RPC structure", _jsonrpc_content);
        _server.sending().push(
            /// @todo Скорректировать коды (и тексты) ошибок
            simodo::variable::JsonRpc(-1, u"Unrecognized JSON-RPC structure", json_rpc.id()));
    }

    if (json_rpc.method() == u"initialize")
        _server.tp().submit(new Initialize(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"initialized")
        _server.tp().submit(new Initialized(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"shutdown")
        _server.tp().submit(new Shutdown(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"textDocument/didOpen")
        _server.tp().submit(new DocDidOpen(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"textDocument/didChange")
        _server.tp().submit(new DocDidChange(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"textDocument/didClose")
        _server.tp().submit(new DocDidClose(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"textDocument/hover")
        _server.tp().submit(new DocHover(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"textDocument/documentSymbol")
        _server.tp().submit(new DocumentSymbol(_server,_jsonrpc_content));
    else if (json_rpc.method().starts_with(u"textDocument/semanticTokens"))
        _server.tp().submit(new SemanticTokens(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"textDocument/declaration")
        _server.tp().submit(new GotoDeclaration(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"textDocument/definition")
        _server.tp().submit(new GotoDefinition(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"textDocument/completion")
        _server.tp().submit(new Completion(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"simodo/command")
        _server.tp().submit(new SimodoCommand(_server,_jsonrpc_content));
    else if (json_rpc.method() == u"SegmentationFault")
        _server.tp().submit(new SegmentationFault(_server,_jsonrpc_content));
    else {
        _server.log().warning("Unsupported method '" + inout::toU8(json_rpc.method()) + "'", _jsonrpc_content);
        _server.sending().push(
            /// @todo Скорректировать коды (и тексты) ошибок
            simodo::variable::JsonRpc(-1, u"Unsupported method '" + json_rpc.method() + u"'", json_rpc.id()));
    }
}

}